package rpa

import (
	"encoding/json"
	"fmt"
	"git.mycaigou.com/gfyx/common/authorize"
	"git.mycaigou.com/gfyx/micro-gfyx-api/http_server/controller"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/common/errcode"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/rpa"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/utils/jwt"
	rpa_service "git.mycaigou.com/gfyx/micro-gfyx-api/service/rpa"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/gin-gonic/gin"
	"strconv"
)

type RpaController struct {
	controller.BaseController
	rpaService  rpa_service.ByaiServiceIface
	cmdService  rpa_service.RpaCmdServiceIface
	byaiService rpa_service.ByaiServiceIface
}

func NewRpaController(
	rpaService rpa_service.ByaiServiceIface,
	cmdService rpa_service.RpaCmdServiceIface,
	byaiService rpa_service.ByaiServiceIface,
) *RpaController {
	return &RpaController{
		rpaService:  rpaService,
		cmdService:  cmdService,
		byaiService: byaiService,
	}
}

// RegisterRouter
// 注册路由
func (c *RpaController) RegisterRouter(g *gin.RouterGroup) {
	// rpa启动
	g.POST("/rpa/start", c.Start)

	// 上报数据
	g.POST("/rpa/transfer", c.Transfer)

	// 建议10s上报一次心跳，可监控客户端是否在线 or 离线
	g.POST("/rpa/heartbeat", c.HeartBeat)

	// 测试目的
	{
		g.GET("/rpa/byai/get-token", c.GetToken)
		g.GET("/rpa/byai/task-detail", c.GetTaskDetail)
		g.POST("/rpa/byai/task-import-data", c.ImportCustomerToTask)
		g.POST("/rpa/byai/create-task", c.CreateByAiTask)
		g.POST("/rpa/byai/exec-task", c.ExecuteByAiTask)
		g.GET("/rpa/init", c.RpaInit)
	}
}

func (c *RpaController) RpaInit(ctx *gin.Context) {
	tenantCode := ctx.Query("tenant_code")
	userMobile := ctx.Query("user_mobile")
	version := ctx.Query("version")
	rpaVersion := ctx.Query("rpa_version")
	//machineCode := ctx.Query("machine_code")
	if tenantCode == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "租户号参数为空")
		return
	}
	if userMobile == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "客户手机号参数为空")
		return
	}

	ctx.Set(authorize.TENANT_CODE_KEY, tenantCode)
	secret, err := c.cmdService.RpaTenantInit(ctx, tenantCode, userMobile, version, rpaVersion)
	if err != nil {
		stark.Logger.Errorf(ctx, "RpaInit-controller-err: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, map[string]interface{}{
		"secret": secret,
	})
}

func (c *RpaController) ExecuteByAiTask(ctx *gin.Context) {
	taskIdStr := ctx.Query("task_id")
	if taskIdStr == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "任务编号为空")
		return
	}

	taskId, _ := strconv.Atoi(taskIdStr)
	_, err := c.byaiService.ExecuteByAiTask(ctx, int64(taskId), rpa.COMPANYID, 1)
	if err != nil {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, nil)
}

func (c *RpaController) ImportCustomerToTask(ctx *gin.Context) {
	taskIdStr := ctx.Query("task_id")
	if taskIdStr == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "任务编号为空")
		return
	}

	taskId, _ := strconv.Atoi(taskIdStr)

	var param = &rpa.CustomerInfoItem{}
	if err := ctx.ShouldBind(param); err != nil {
		stark.Logger.Infof(ctx, "rpa-ImportCustomerToTask-error: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	if param.Phone == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "手机号为空")
		return
	}

	list := make([]*rpa.CustomerInfoItem, 0)
	list = append(list, param)
	_, err := c.byaiService.ImportCustomerToTask(ctx, int64(taskId), rpa.COMPANYID, list)
	if err != nil {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, param)
}

func (c *RpaController) CreateByAiTask(ctx *gin.Context) {
	authInfo, err := jwt.GetAuthInfo(ctx)
	if err != nil {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}
	param := &rpa.ByAiTask{
		CallJobName:      fmt.Sprintf("外呼任务-%s", authInfo.TenantCode),
		CallJobType:      2,
		CompanyId:        rpa.COMPANYID,
		ConcurrencyNum:   4,
		ConcurrencyQuota: 2,
		Remark:           "rpa调度自动创建任务",
		RobotDefId:       333099,
		UserPhoneIds:     []int32{274442},
		PermitRepeatNum:  true,
	}

	taskId, err := c.byaiService.CreateByAiTask(ctx, param)
	if err != nil {
		stark.Logger.Infof(ctx, "CreateByAiTask-controller-err: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, map[string]interface{}{
		"task-id": taskId,
	})
}

func (c *RpaController) GetTaskDetail(ctx *gin.Context) {
	taskIdStr := ctx.Query("task_id")
	if taskIdStr == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "任务编号为空")
		return
	}

	taskId, _ := strconv.Atoi(taskIdStr)
	taskDetail, err := c.byaiService.GetByaiTaskDetail(ctx, int64(taskId), rpa.COMPANYID)
	if err != nil {
		stark.Logger.Infof(ctx, "GetTaskDetail-controller-err: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, taskDetail)
}

func (c *RpaController) HeartBeat(ctx *gin.Context) {
	param := &rpa.RpaCmdData{}
	if err := ctx.ShouldBind(param); err != nil {
		stark.Logger.Infof(ctx, "rpa-Start-error: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	stark.Logger.Infof(ctx, "HeartBeat-params: %+v", param)
	c.Success(ctx, nil)
}

// rpa启动
func (c *RpaController) Start(ctx *gin.Context) {
	param := &rpa.RpaStartParam{}
	if err := ctx.ShouldBind(param); err != nil {
		stark.Logger.Infof(ctx, "rpa-Start-error: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	if param.TenantCode == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "租户编号为空")
		return
	}

	if param.Secret == "" {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "密钥为空")
		return
	}

	if (param.UserMobile == "") || len(param.UserMobile) != 11 {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "非法手机号")
		return
	}
	ctx.Set(authorize.TENANT_CODE_KEY, param.TenantCode)

	jwtToken, err := c.cmdService.RpaStart(ctx, param)
	if err != nil {
		c.Fail(ctx, errcode.COMMON_ERROR, err.Error())
		return
	}

	c.Success(ctx, map[string]interface{}{
		"token": jwtToken,
	})
}

// 传输数据
func (c *RpaController) Transfer(ctx *gin.Context) {
	param := &rpa.RpaCmdData{}
	if err := ctx.ShouldBind(param); err != nil {
		stark.Logger.Infof(ctx, "rpa-Transfer-param: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	if param.Message == nil {
		stark.Logger.Infof(ctx, "rpa-Transfer-param: %+v", param)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "上报消息体为空")
		return
	}

	if param.Message.Data != "" {
		var data interface{}
		err := json.Unmarshal([]byte(param.Message.Data), &data)
		if err != nil {
			stark.Logger.Infof(ctx, "rpa-Transfer-param-err: %+v, param: %+v, message: %+v", err, param, param.Message)
			c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "消息内容json解析失败")
			return
		}
	}

	if param.Version <= 0 {
		stark.Logger.Infof(ctx, "rpa-Transfer-param: %+v", param)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "version非法的协议值")
		return
	}

	if param.RpaVersion == "" {
		stark.Logger.Infof(ctx, "rpa-Transfer-param: %+v", param)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "RpaVersion为空")
		return
	}

	data, err := c.cmdService.RpaCmdMain(ctx, param)
	if err != nil {
		stark.Logger.Infof(ctx, "rpa-Transfer-error: %+v, param: %+v", err, param)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	stark.Logger.Infof(ctx, "Transfer-message-param: %+v, message: %+v, data: %+v", param, param.Message, data)

	c.Success(ctx, data)
}

// 测试目的
func (c *RpaController) GetToken(ctx *gin.Context) {
	ak, err := c.rpaService.GetByaiToken(ctx, rpa.COMPANYID, rpa.APP_KEY, rpa.APP_SECRET)
	if err != nil {
		stark.Logger.Infof(ctx, "GetToken-error: %+v", err)
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}

	c.Success(ctx, map[string]interface{}{
		"ak": ak,
	})
}
